


*******************************************************************************************************
*************** Replication file for 'Which Historical Forecast Model Performs Best?' *****************
************************ Éric Bélanger, Fernando Feitosa and Mathieu Turgeon **************************
*******************************************************************************************************

set scheme lean1
cd "~/Dropbox/Forecast 2022 French Elections/Data"
use "Replication_files.dta", clear

egen year_new = group(year) 

* 1965-2017 election forecast
* Iowa model estimation:

quietly {
forvalues count =1/10 {
	reg vleft pop_adjusted unemp_adjusted if count!=`count'
	predict pvote`count'
	predict stdp`count', stdp
	egen pv`count'=mean(pvote`count') if count==`count'
	recode pv`count' (.=1)
	egen se`count'=mean(stdp`count') if count==`count'
	recode se`count' (.=1)
	}
	
gen pvote=1
forvalues count = 1/10 {
	replace pvote = pvote*pv`count'
	}
gen serror=1
forvalues count = 1/10 {
	replace serror = serror*se`count'
	}
gen perror = pvote - vleft
gen mae = sqrt((perror)^2)
drop pv1-pv10 pvote1-pvote10 se1-se10 
}
gen lower_ci = pvote-(serror*2.306)
gen upper_ci = pvote+(serror*2.306) 
egen mae_all = mean(abs(mae))
replace mae_all = . if mae ==. 

rename pvote pvote1_iowa 
rename perror perror1_iowa 
rename serror serror1_iowa  
rename lower_ci lower_ci1_iowa  
rename upper_ci upper_ci1_iowa  
rename mae mae1_iowa
rename mae_all mae_all1_iowa   

reg vleft pop_adjusted unemp_adjusted
estimates store results1_iowa
			 
* Proxy model estimation:

quietly {
forvalues count =1/10 {
	reg vleft epi if count!=`count'
	predict pvote`count'
	predict stdp`count', stdp
	egen pv`count'=mean(pvote`count') if count==`count'
	recode pv`count' (.=1)
	egen se`count'=mean(stdp`count') if count==`count'
	recode se`count' (.=1)
	}
	
gen pvote=1
forvalues count = 1/10 {
	replace pvote = pvote*pv`count'
	}
gen serror=1
forvalues count = 1/10 {
	replace serror = serror*se`count'
	}
gen perror = pvote - vleft
gen mae = sqrt((perror)^2)
drop pv1-pv10 pvote1-pvote10 se1-se10 
}
gen lower_ci = pvote-(serror*2.306)
gen upper_ci = pvote+(serror*2.306) 
egen mae_all = mean(abs(mae))
replace mae_all = . if mae ==. 
	
rename pvote pvote1_proxy 
rename perror perror1_proxy 
rename serror serror1_proxy  
rename lower_ci lower_ci1_proxy  
rename upper_ci upper_ci1_proxy  
rename mae mae1_proxy 
rename mae_all mae_all1_proxy  

reg vleft epi
estimates store results1_proxy

* Figure 1 (Iowa model):

graph twoway  (scatter vleft pvote1_iowa year_new if year_new < 11, c(L) xtitle("") ///
             ytitle("Left Candidates - Vote (%)") ms(O Oh) msize(.8 .8) ///
			 xlabel(1 "1965" 2 "1969" 3"1974" 4"1981" 5"1988" 6"1995" 7"2002" 8"2007" 9"2012" 10"2017") ) ///
			  (rspike vleft pvote1_iowa year_new if year_new < 11, c(none L) lpattern(dash) ///
			  xtitle("") ylabel(20(10)60) ///
             ytitle("Left Candidates - Vote (%)") msize(.5) ///
			 xlabel(1 "1965" 2 "1969" 3"1974" 4"1981" 5"1988" 6"1995" 7"2002" 8"2007" 9"2012" 10"2017") legend(off) )

* Figure 1 (proxy model):
			 
graph twoway  (scatter vleft pvote1_proxy year_new if year_new < 11, c(L) xtitle("") ///
             ytitle("Left Candidates - Vote (%)") ms(O Oh) msize(.8 .8) ///
			 xlabel(1 "1965" 2 "1969" 3"1974" 4"1981" 5"1988" 6"1995" 7"2002" 8"2007" 9"2012" 10"2017") ) ///
			  (rspike vleft pvote1_proxy year_new if year_new < 11, c(none L) lpattern(dash) ///
			  xtitle("") ///
             ytitle("Left Candidates - Vote (%)") msize(.5) ///
			 xlabel(1 "1965" 2 "1969" 3"1974" 4"1981" 5"1988" 6"1995" 7"2002" 8"2007" 9"2012" 10"2017" ) legend(off) )

* 2022 election forecast			 
* Proxy model estimation (round 1):

quietly {
forvalues count =1/11 {
	reg vleft epi if count!=`count'
	predict pvote`count'
	predict stdp`count', stdp
	egen pv`count'=mean(pvote`count') if count==`count'
	recode pv`count' (.=1)
	egen se`count'=mean(stdp`count') if count==`count'
	recode se`count' (.=1)
	}
	
gen pvote=1
forvalues count = 1/11 {
	replace pvote = pvote*pv`count'
	}
gen serror=1
forvalues count = 1/11 {
	replace serror = serror*se`count'
	}
gen perror = pvote - vleft
gen mae = sqrt((perror)^2)
drop pv1-pv11 pvote1-pvote11 se1-se11 
}
gen lower_ci = pvote-(serror*2.306)
gen upper_ci = pvote+(serror*2.306) 

rename pvote pvote1_proxy2022 
rename perror perror1_proxy2022 
rename serror serror1_proxy2022 
rename lower_ci lower_ci1_proxy2022  
rename upper_ci upper_ci1_proxy2022  
rename mae mae1_proxy2022 
				
* Proxy model estimation (round 2):

quietly {
forvalues count =1/11 {
	reg vleft2 epi if count!=`count'
	predict pvote`count'
	predict stdp`count', stdp
	egen pv`count'=mean(pvote`count') if count==`count'
	recode pv`count' (.=1)
	egen se`count'=mean(stdp`count') if count==`count'
	recode se`count' (.=1)
	}
	
gen pvote=1
forvalues count = 1/11 {
	replace pvote = pvote*pv`count'
	}
gen serror=1
forvalues count = 1/11 {
	replace serror = serror*se`count'
	}
gen perror = pvote - vleft2
gen mae = sqrt((perror)^2)
drop pv1-pv11 pvote1-pvote11 se1-se11 
}
gen lower_ci = pvote-(serror*2.306)
gen upper_ci = pvote+(serror*2.306) 
egen mae_all = mean(abs(mae))
replace mae_all = . if mae ==. 
	
rename pvote pvote2_proxy2022 
rename perror perror2_proxy2022 
rename serror serror2_proxy2022  
rename lower_ci lower_ci2_proxy2022  
rename upper_ci upper_ci2_proxy2022  
rename mae mae2_proxy2022
rename mae_all mae_all2_proxy2022 

reg vleft2 epi
estimates store results2_proxy

* Estimations in the text:
	
list year pvote1_proxy mae1_proxy mae_all1_proxy if year == 2017
list year mae_all1_iowa if year != 2022
list year mae_all1_proxy if year != 2022
list year pvote1_proxy2022 serror1_proxy2022 lower_ci1_proxy2022 upper_ci1_proxy2022 if year == 2022
list year pvote2_proxy2022 serror2_proxy2022 lower_ci2_proxy2022 upper_ci2_proxy2022 if year == 2022
esttab results1_iowa results1_proxy results2_proxy using results.rtf, replace p(2) b(2) compress
list year mae_all2_proxy2022  

* Online appendix:		

list year pvote1_iowa serror1_iowa lower_ci1_iowa upper_ci1_iowa vleft if year != 2022
list year pvote1_proxy serror1_proxy lower_ci1_proxy upper_ci1_proxy vleft if year != 2022



